﻿using DbContext;
using MathNet.Numerics;
using NPOI.HSSF.Record;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using SmartPlant.Core;
using SmartPlant.Core.Mvvm;
using SmartPlant.Model;
using SmartPlant.Model.Biz;
using SmartPlant.Model.DbContext;
using SmartPlant.Services;
using SmartPlant.Services.Interfaces;
using SmartPlant.WinCore;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Map;
using Telerik.Windows.Diagrams.Core;
using Telerik.Windows.Documents.Model.Revisions;
using Telerik.Windows.Documents.RichTextBoxCommands;
using Telerik.Windows.Persistence.Core;
using Unity;
using DrawingService = SmartPlant.Services.DrawingService;

namespace SmartPlant.Modules.Base.ViewModels
{
    public class RevisionManagerViewModel : RegionViewModelBase, IDialogAware
    {
        private string ProjectID { get; set; }
        private decimal DwgID { get; set; }
        private DbContext.Revision _selectedRevision;
        public DbContext.Revision SelectedRevision
        {
            get { return _selectedRevision; }
            set
            {
                if (SetProperty(ref _selectedRevision, value))
                {
                    DeleteRevisionCommand.RaiseCanExecuteChanged();  
                }
            }
        }

        public ObservableCollection<DbContext.Revision> Revisions2
        { get; set; }
        private ObservableCollection<DbContext.Revision> _Revisions;

        public ObservableCollection<DbContext.Revision> Revisions
        {
            get { return _Revisions; }
            set
            {
                SetProperty(ref _Revisions, value);
               
            }
        }
        private bool _IsUpdating;

        public bool IsUpdating
        {
            get { return _IsUpdating; }
            set
            {
                SetProperty(ref _IsUpdating, value);
            }
        }
        private Drawing _DrawData;

        public Drawing DrawData
        {
            get { return _DrawData; }
            set
            {
                SetProperty(ref _DrawData, value);
            }
        }

        private readonly IRevisionService RevisionServ;
        private readonly Services.Interfaces.IDrawingService DrawServ;
        private void Revisions_Changed(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add ||
                e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove ||
                e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace ||
                e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
            {
                UpdateMaxRevId();
            }
        }
        private void UpdateMaxRevId()
        {
            if (Revisions.Any())
            {
                MaxRevId = Revisions.Max(r => r.RevId);
            }
            else
            {
                MaxRevId = 0M;  
            }
        }

        public RevisionManagerViewModel(IRegionManager regionManager, IUnityContainer unityContainer, IDialogService dialogService) : base(regionManager, unityContainer, dialogService)
        {
            DrawServ = unityContainer.Resolve<DrawingService>();
            RevisionServ = unityContainer.Resolve<RevisionService>();
            ProjectID = GlobalObject.CurrentProject.ProjId.ToString();
            Revisions = new ObservableCollection<DbContext.Revision>();
            Revisions2 = new ObservableCollection<DbContext.Revision>();
            Revisions.CollectionChanged += Revisions_Changed;
            AddNewRevisionCommand = new Prism.Commands.DelegateCommand(AddNewRevision);
            DeleteRevisionCommand = new Prism.Commands.DelegateCommand(DeleteRevision, CanDeleteRevision);
            CancelCommand = new Prism.Commands.DelegateCommand(ExecuteCancelCommand);
        }

        public new string Title
        {
            get
            {
                return "版次管理";
            }
        }

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
            
        }
        private DelegateCommand<object> _ConfirmCommand;

        public DelegateCommand<object> ConfirmCommand
        {
            get
            {
                if (_ConfirmCommand != null) return _ConfirmCommand;
                _ConfirmCommand = new DelegateCommand<object>(onSaveCommandAsync);
                return _ConfirmCommand;
            }
        }

        public Prism.Commands.DelegateCommand AddNewRevisionCommand { get; private set; }
        public Prism.Commands.DelegateCommand DeleteRevisionCommand { get; private set; }
        public Prism.Commands.DelegateCommand CancelCommand { get; private set; }
        private decimal _maxRevId;
        public decimal MaxRevId
        {
            get => _maxRevId;
            set
            {
                if (_maxRevId != value)
                {
                    _maxRevId = value;
                    OnPropertyChanged(nameof(MaxRevId));  
                }
            }
        }

        private bool CanDeleteRevision()
        {
            return SelectedRevision != null;
        }
        private void ExecuteCancelCommand()
        {
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
        }
        private void DeleteRevision()
        {
            if (SelectedRevision != null)
            {
                Revisions.Remove(SelectedRevision);
            }
        }
        public void AddNewRevision()
        {
            var newRevision = new DbContext.Revision {
                UserName = GlobalObject.currentUser,
                RevId = MaxRevId + 1m,
                ChgDate = DateTime.Now
        };
            Revisions.Add(newRevision);
        }


        public async void onSaveCommandAsync(object obj)
        {
            var Revisiondata = await RevisionServ.GetById(DwgID);

            if (Revisiondata != null)
            {
                foreach (var revision in Revisiondata)
                {
                    if (revision.RevNo != "#")
                    {
                        Revisions2.Add(revision); ;
                    }
                }
            }
            var currentRevIds = Revisions.Select(r => r.RevId).ToList();
            var originalRevIds = Revisions2.Select(r => r.RevId).ToList();
            var revIdsToDelete = originalRevIds.Except(currentRevIds).ToList();
            var revIdsToAdd = currentRevIds.Except(originalRevIds).ToList();
            var revIdsToUpdate = currentRevIds.Intersect(originalRevIds).ToList();
            var res = await DrawServ.UpdateDrawingAsync(Convert.ToDecimal(ProjectID), DrawData);
            foreach (var revId in revIdsToDelete)
            {
                var revisionToDelete = Revisions2.First(r => r.RevId == revId);
                var deleteResult = await RevisionServ.DeleteRevisionAsync(Convert.ToDecimal(ProjectID), revisionToDelete.DwgId, revisionToDelete.RevId);
            }
            foreach (var revId in revIdsToAdd)
            {
                var revisionToAdd = Revisions.First(r => r.RevId == revId);
                revisionToAdd.DwgId = DwgID; 
                var insertResult = await RevisionServ.InsertRevisionAsync(Convert.ToDecimal(ProjectID), revisionToAdd);
            }
            foreach (var revId in revIdsToUpdate)
            {
                var currentRevision = Revisions.First(r => r.RevId == revId);
                var originalRevision = Revisions2.First(r => r.RevId == revId);
                if (currentRevision.RevCreateBy != originalRevision.RevCreateBy ||
                    currentRevision.RevDesc != originalRevision.RevDesc ||
                    currentRevision.RevChkBy != originalRevision.RevChkBy ||
                    currentRevision.RevApprBy != originalRevision.RevApprBy ||
                    currentRevision.RevSign != originalRevision.RevSign ||
                    currentRevision.RevNo != originalRevision.RevNo ||
                    currentRevision.RevDate != originalRevision.RevDate)
                {
                    var updateResult = await RevisionServ.UpdateRevisionAsync(Convert.ToDecimal(ProjectID), currentRevision);
                }
            }
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK));


        }
        /// <summary>
        /// dwgid
        /// </summary>
        /// <param name="parameters"></param>

        public async void OnDialogOpened(IDialogParameters parameters)
        {
            if (parameters.ContainsKey(DialogParameterKeys.Id))
            {
                DwgID = parameters.GetValue<decimal>(DialogParameterKeys.Id);
                var Revisiondata = await RevisionServ.GetById(DwgID);

                 DrawData =   await DrawServ.GetById( DwgID);
                if (Revisiondata != null)
                {
                    foreach (var revision in Revisiondata)
                    {
                        if (revision.RevNo != "#")
                        {
                            Revisions.Add(revision);

                        }
                    }
                }
            }
            
        }

    }
}
